//
//  NSObject+ModelJson.m
//  ReviewDemo
//
//  Created by 苏沫离 on 2018/3/19.
//  Copyright © 2018年 long. All rights reserved.
//

#import "NSObject+ModelJson.h"
#import <objc/runtime.h>
#import <objc/message.h>

@implementation NSObject (ModelJson)

+ (instancetype)modelWithParserDict:(NSDictionary *)dict
{
    id objc = objc_msgSend(self, sel_registerName("alloc"));
    objc = objc_msgSend(objc, sel_registerName("init"));
    unsigned int count = 0;
    Ivar *ivarList = class_copyIvarList(self, &count);
    for (int i = 0; i < count; i ++)
    {
        Ivar theIvar = ivarList[i];
        NSString *key = [NSString stringWithUTF8String:ivar_getName(theIvar)];
        key = [key substringFromIndex:1];
        id theValue = dict[key];
        NSString *varType = [NSString stringWithUTF8String:ivar_getTypeEncoding(theIvar)];
        varType = [varType stringByReplacingOccurrencesOfString:@"\"" withString:@""];
        varType = [varType stringByReplacingOccurrencesOfString:@"@" withString:@""];
        if ([theValue isKindOfClass:[NSDictionary class]] &&
            [varType hasPrefix:@"NS"] == NO)
        {
            Class dictModel = NSClassFromString(varType);
            theValue = [dictModel modelWithParserDict:theValue];
        }
        if ([theValue isKindOfClass:[NSArray class]])
        {
            if ([self respondsToSelector:@selector(arrayContainModelClass)])
            {
                id idSelf = self;
                NSString *typeArray = [idSelf arrayContainModelClass][key];
                Class arrayModel = NSClassFromString(typeArray);
                NSMutableArray *array = [NSMutableArray array];
                for (NSDictionary *arrDict in theValue)
                {
                    [array addObject:[arrayModel modelWithParserDict:arrDict]];
                }
                theValue = array;
            }
        }
        if (theValue)
        {
            [objc setValue:theValue forKey:key];
        }
    }
    free(ivarList);
    return objc;
}

//Case 1 ：模型属性数量大于字典的键值对
+ (instancetype)modelWithDict1:(NSDictionary *)dict
{
    id objc = [[self alloc] init];
    unsigned int count = 0;
    Ivar *ivarList = class_copyIvarList(self, &count);
    for (int i = 0; i < count; i ++)
    {
        Ivar ivar = ivarList[i];
        NSString *key = [NSString stringWithUTF8String:ivar_getName(ivar)];
        key = [key substringFromIndex:1];//去掉第一个下划线 _
        id value = dict[key];
        if (value)
        {
            [objc setValue:value forKey:key];
        }
    }
    free(ivarList);
    return objc;
}


//Case 2 ：模型中嵌套模型：模型属性是另外一个模型对象
+ (instancetype)modelWithDict2:(NSDictionary *)dict
{
    id objc = [[self alloc] init];
    unsigned int count = 0;
    Ivar *ivarList = class_copyIvarList(self, &count);
    for (int i = 0; i < count; i ++)
    {
        Ivar ivar = ivarList[i];
        NSString *key = [NSString stringWithUTF8String:ivar_getName(ivar)];
        
        key = [key substringFromIndex:1];//去掉第一个下划线 _
        id value = dict[key];
        NSString *type = [NSString stringWithUTF8String:ivar_getTypeEncoding(ivar)];
        type = [type stringByReplacingOccurrencesOfString:@"\"" withString:@""];
        type = [type stringByReplacingOccurrencesOfString:@"@" withString:@""];
        
        /*  B(BOOL)       @"NSString"   f(float)    q(NSInteger)
            @"NSArray"    @"NSDictionary"  @"CarModel"
         */
        NSLog(@"key : %@======== type : %@",key,type);

        //自定义对象才转 
        if ([value isKindOfClass:[NSDictionary class]] &&
            [type hasPrefix:@"NS"] == NO)
        {
            Class modelClass = NSClassFromString(type);
            if (modelClass)
            {
                value = [modelClass modelWithDict3:value];
            }
        }
        
        
        if (value)
        {
            [objc setValue:value forKey:key];
        }
    }
    free(ivarList);
    return objc;
}

//Case 3 ：数组中装着模型（模型的属性是一个数组，数组中是一个个模型对象）
+ (instancetype)modelWithDict3:(NSDictionary *)dict
{
    id objc = [[self alloc] init];
    unsigned int count = 0;
    Ivar *ivarList = class_copyIvarList(self, &count);
    for (int i = 0; i < count; i ++)
    {
        Ivar ivar = ivarList[i];
        NSString *key = [NSString stringWithUTF8String:ivar_getName(ivar)];
        key = [key substringFromIndex:1];//去掉第一个下划线 _
        id value = dict[key];
        NSString *type = [NSString stringWithUTF8String:ivar_getTypeEncoding(ivar)];
        /*  B(BOOL)       @"NSString"   f(float)    q(NSInteger)
         @"NSArray"    @"NSDictionary"  @"CarModel"
         */
        type = [type stringByReplacingOccurrencesOfString:@"\"" withString:@""];
        type = [type stringByReplacingOccurrencesOfString:@"@" withString:@""];
        
        
        NSLog(@"key : %@======== type : %@",key,type);
        
        if ([value isKindOfClass:[NSArray class]])
        {
            if ([self respondsToSelector:@selector(arrayContainModelClass)])
            {
                id idSelf = self;// 转换成id类型，就能调用任何对象的方法
                NSString *type1 = [idSelf arrayContainModelClass][key];// 获取数组中字典对应的模型
                NSLog(@"type1 ======== %@",type1);
                // 生成模型
                Class classModel = NSClassFromString(type1);
                NSMutableArray *arrM = [NSMutableArray array];
                // 遍历字典数组，生成模型数组
                for (NSDictionary *dict in value) {
                    // 字典转模型
                    id model =  [classModel modelWithDict3:dict];
                    [arrM addObject:model];
                }
                
                // 把模型数组赋值给value
                value = arrM;
            }
        }
        
        
        if (value)
        {
            [objc setValue:value forKey:key];
        }
    }
    free(ivarList);
    return objc;
}


@end
